package com.imflea.zero.service.qx.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imflea.zero.utils.ZeroApplicationContextUtil;
import com.imflea.zero.util.ZeroCacheUtils;
import com.imflea.zero.util.base.CommonUtils;
import com.imflea.zero.exception.BizException;
import com.imflea.zero.model.dao.qx.QxCacheInfoMapper;
import com.imflea.zero.model.entity.qx.QxCacheInfo;
import com.imflea.zero.model.entity.qx.dto.QxCacheInfoDto;
import com.imflea.zero.service.qx.IQxCacheInfoService;
import com.imflea.zero.task.QxRedisTask;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 缓存基本信息 服务实现类
 * </p>
 *
 * @author xiangbaoyu
 * @since 2021-09-17
 */
@Service
public class QxCacheInfoServiceImpl extends ServiceImpl<QxCacheInfoMapper, QxCacheInfo> implements IQxCacheInfoService {

    @Override
    public QxCacheInfo saveOrUpdateQxCacheInfo(QxCacheInfo entity) {
        if (CommonUtils.isNull(entity.getId())) {
            entity.setId(CommonUtils.generateRandomString());
        }
        this.saveOrUpdate(entity);
        return entity;
    }

    @Override
    public PageInfo<QxCacheInfo> queryPage(QxCacheInfoDto dto) {
        Integer pageIndex = dto.getPageNum();
        Integer pageSize = dto.getPageSize();
        QueryWrapper<QxCacheInfo> queryWrapper = new QueryWrapper<>();
        PageHelper.startPage(pageIndex, pageSize);
        List<QxCacheInfo> adoptInfos = this.list(queryWrapper);
        PageInfo<QxCacheInfo> pageResult = new PageInfo<>(adoptInfos);
        return pageResult;
    }


    @Override
    public List<Map<String, Object>> queryTableDataByQuerySql(String dataQuerySql) {
        return this.getBaseMapper().queryAllTableData(dataQuerySql);
    }


    @Override
    public boolean refreshCacheByTableName(List<String> tableNames) {

        List<QxCacheInfo> redisGrid = null;
        if (CommonUtils.isNull(tableNames)) {
            redisGrid = this.list();
        } else {
            redisGrid = this.queryByTablesNames(tableNames);
        }
        return this.queryAndRefreshCache(redisGrid);
    }

    @Override
    public boolean refreshCacheByTableName(String tableName) throws BizException {
        if (CommonUtils.isNull(tableName)) {
            throw new BizException("表名不可为空");
        }
        QxCacheInfo cacheInfo = this.queryByTablesName(tableName);
        if (CommonUtils.isNull(cacheInfo)) {
            throw new BizException("无效的表名称");
        }
        List<QxCacheInfo> redisGrid = new ArrayList<>();
        redisGrid.add(cacheInfo);
        return this.queryAndRefreshCache(redisGrid);
    }

    @Override
    public List<QxCacheInfo> queryAll(String tableName) {

        if (CommonUtils.isNull(tableName)) {
            return this.list();
        } else {
            QueryWrapper<QxCacheInfo> queryWrapper = new QueryWrapper();
            queryWrapper.like("table_name", tableName);
            return this.list(queryWrapper);
        }
    }

    @Override
    public boolean queryAndRefreshCache(List<QxCacheInfo> redisGrid) {
        try {
            final List<Map<String, String>> redisList = new ArrayList<Map<String, String>>();
            for (QxCacheInfo po : redisGrid) {
                final String tableName = po.getTableName();
                final String dataQuerySql = po.getDataQuerySql();
                final String indexColumns = po.getIndexColumns();
                final String indexCaption = po.getIndexCaption();
                final String groupIndex = po.getGroupIndex();
                final String redisType = po.getRedisType();
                final Map<String, String> paramMap = new HashMap<String, String>();
                paramMap.put("tableName", tableName);
                paramMap.put("dataQuerySql", dataQuerySql);
                paramMap.put("indexColumns", indexColumns);
                paramMap.put("indexCaption", indexCaption);
                paramMap.put("groupIndex", groupIndex);
                paramMap.put("redisType", redisType);
                redisList.add(paramMap);
            }
            // 开始删除redis
            final Set<String> keys = new HashSet<String>();
            for (Map<String, String> map : redisList) {
                final String tableName = map.get("tableName");
                final String fl = "YWB";
                final String redisMapKey = "Map:" + fl + ":" + tableName.toUpperCase() + ":*";
                final String redisStringKey = "String:" + fl + ":" + tableName.toUpperCase() + ":*";
                final String redisListKey = "List:" + fl + ":" + tableName.toUpperCase() + ":*";

                final Set<String> redisMapKeySet =ZeroCacheUtils.getKeys(redisMapKey);
                final Set<String> redisStringKeySet =ZeroCacheUtils.getKeys(redisStringKey);
                final Set<String> redisListKeySet =ZeroCacheUtils.getKeys(redisListKey);
                keys.addAll(redisMapKeySet);
                keys.addAll(redisStringKeySet);
                keys.addAll(redisListKeySet);
            }
            if (!CommonUtils.isNull(keys)) {
               ZeroCacheUtils.deleteKey(keys.toArray(new String[keys.size()]));
            }
            // 保存redis
            for (Map<String, String> map : redisList) {
                final QxRedisTask redisTask = ZeroApplicationContextUtil.getBean("qxRedisTask", QxRedisTask.class);
                List<Map<String, Object>> dataList = this.queryTableDataByQuerySql(map.get("dataQuerySql"));
                redisTask.setParam(map);
                redisTask.setDataList(dataList);
                redisTask.start();
            }
        } catch (
                Exception e) {
            throw new BizException("缓存刷新异常：" + e.getMessage());
        }
        return true;
    }

    @Override
    public List<QxCacheInfo> queryByTablesNames(List<String> tableNames) {
        if (CommonUtils.isNull(tableNames)) {
            throw new BizException("请求参数为空：tableNames");
        }
        QueryWrapper<QxCacheInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("table_name", tableNames);
        return this.list(queryWrapper);
    }

    @Override
    public QxCacheInfo queryByTablesName(String tableName) {
        if (CommonUtils.isNull(tableName)) {
            throw new BizException("请求参数为空：tableName");
        }
        QueryWrapper<QxCacheInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("table_name", tableName);
        return this.getOne(queryWrapper);
    }

}
